package gov.pbc.nn.kjgl.software.dao;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.bstek.bdf2.core.business.IDept;
import com.bstek.bdf2.core.business.IUser;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.bdf.service.DeptService;
import gov.pbc.nn.core.bdf.service.DeptService.DefaultDeptRowMapper;
import gov.pbc.nn.core.dao.AbstractHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.dao.PbcnnCoreJdbcDao;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.Constants;
import gov.pbc.nn.kjgl.entity.Project;
import gov.pbc.nn.kjgl.entity.ProjectChange;
import gov.pbc.nn.kjgl.entity.ProjectFile;
import gov.pbc.nn.kjgl.entity.ProjectProblem;
import gov.pbc.nn.kjgl.entity.ProjectTask;
import gov.pbc.nn.uflo.entity.Opinion;

@Repository
public class ChangeProjectDao extends AbstractHibernateDao {

//	@Autowired
//	private DeptService deptService;
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;
	/**
	 * 变更表数据
	 * 
	 * @param page
	 * @param projectId
	 */
	public void getProjectChange(Page<ProjectChange> page, Criteria criteria, String id) {
		DetachedCriteria query = this.buildDetachedCriteria(criteria, ProjectChange.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("projectId", id));
		query.add(Restrictions.eq("createUser", ContextHolder.getLoginUserName()));
		this.pagingQuery(page, query);
	}

	/**
	 * 查询 项目变更文件（问题管理文件 type=4）
	 * 
	 * @return
	 */
	public void getProjectFile(Page<ProjectFile> page, String id) {
		DetachedCriteria query = DetachedCriteria.forClass(ProjectFile.class);
		query.add(Restrictions.or(Restrictions.eq("invalid", false), Restrictions.isNull("invalid")));
		query.add(Restrictions.eq("type", 4));
		query.add(Restrictions.eq("ownerId", id));
		this.pagingQuery(page, query);
	}

	/**
	 * 删除变更项目和文件
	 * 
	 * @param list
	 */
	public void delete(List<String> list) {
		String hql = "select id from ProjectFile where invalid=false and ownerId=:id";
		Map<String, Object> map = new HashMap<String, Object>();
		for (String id : list) {
			map.put("id", id);
			List<String> ls = this.query(hql, map);
			if (ls.size() > 0) {
				for (String pid : ls) {
					this.delete(pid, ProjectFile.class);
				}
			}
			this.delete(id, ProjectChange.class);
		}
	}

	/**
	 * 判断当前登陆人 所在部门 是业务部门 还是科技部门 如果是科技部门 返回 false 如果是业务部门 返回 true
	 * 
	 * @return
	 */
	public boolean getDept(String deptId) {
		String dept = ContextHolder.getLoginUser().getDepts().get(0).getId();
		if (dept.equals(deptId)) {
			return true;
		} else {
			return false;
		}

	}

	/**
	 * 保存添加变更项目
	 * 
	 * @param projectProblem
	 * @throws IOException
	 */
	public void saveProjectChange(ProjectChange projectChange, String Id) throws IOException {
		EntityState state = EntityUtils.getState(projectChange);
		if (state.equals(EntityState.NEW)) {// 新增的时候执行
			// 保存表数据 新增状态为4,提交状态为5
			projectChange.setState(4);
			projectChange.setProjectId(Id);
			this.save(projectChange);
			// 得到 上传文件内容
			List<ProjectFile> files = EntityUtils.getValue(projectChange, "dataSetFile");
			if (files != null) {
				// 声明一个map集合，将临时路径存进去，否则在保存实际路径的时候会将临时路径覆盖
				Map<String, String> tmpMap = new HashMap<String, String>();
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					pf.setOwnerId(projectChange.getId());
					pf.setType(4);
					tmpMap.put("File" + i, pf.getPath());// map存放临时路径,没有保存到数据库中。（缓存）
					pf.setPath(this.getRealPath().toString());// 将实际路径保存到数据库中
					this.save(pf);
				}
				for (int i = 0; i < files.size(); i++) {
					ProjectFile pf = files.get(i);
					String key = "File" + i;
					String tmpPath = tmpMap.get(key);// 根据key 得到临时路径
					this.transterFile(tmpPath, pf.getPath());// 临时文件更新为实际路径
				}
			}
		} else if (state.equals(EntityState.MODIFIED)) {
			this.update(projectChange);
		}
	}
	
	/**
	 * 得到实际文件路径
	 * 
	 * @return
	 * @throws IOException
	 */
	public Path getRealPath() throws IOException {
		String basePath = Configure.getString("WENJIAN_FILE_UPLOAD_PATH");
		String pathArr = "项目变更附件";
		Path path = Paths.get(basePath, pathArr);// 组合2个路径
		if (!Files.isDirectory(path)) {
			path = Files.createDirectories(path);
		}
		path = path.resolve(UUID.randomUUID().toString());
		return path;// 上传文件保存后的实际地址
	}

	/**
	 * 将 临时文件路径 更新 实际文件路径
	 * 
	 * @param sourceFile
	 *            实际文件路径
	 * @param targetFile
	 *            临时文件路径
	 * @throws IOException
	 */
	public void transterFile(String sourceFile, String targetFile) throws IOException {
		Path sourcePath = Paths.get(sourceFile);
		Files.copy(sourcePath, Paths.get(targetFile));
	}

	/**
	 * 此方法 忘记哪里有调用了，所以没有注释。
	 * 
	 * 查询 当前登录人所在处室 有 科长 角色的 人员
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getAssessor() {
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(), Constants.ROLE_KZ);
		List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
		// if (users.size() > 0) {
		for (IUser u : users) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("cname", u.getCname());
			map.put("username", u.getUsername());
			map.put("dept", EntityUtils.getValue(u, "deptName"));
			ls.add(map);
		}
		// } else {
		// ls = null;
		// }
		return ls;
	}

	/**
	 * 获取业务需求部门具有科长职位的人 下拉框
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getXqDeptKz(String xqtcDeptId) {
		Dept dept = (Dept) getDeptById(xqtcDeptId);
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren(dept.getCDept().getId(), Constants.ROLE_KZ);
		List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
		if (users.size() > 0) {
			for (IUser u : users) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("cname", u.getCname());
				map.put("username", u.getUsername());
				map.put("dept", EntityUtils.getValue(u, "deptName"));
				ls.add(map);
			}
		} else {
			ls = null;
		}
		return ls;
	}

	/**
	 * 获取科技处具有处长职位的人 下拉框
	 * 
	 * @return
	 */
	public List<Map<String, Object>> getKjcCz() {
		List<IUser> users = SecurityUtils.getUserByRoleForDeptWithChildren("489145101024", Constants.ROLE_CZ);
		List<Map<String, Object>> ls = new ArrayList<Map<String, Object>>();
		if (users.size() > 0) {
			for (IUser u : users) {
				Map<String, Object> map = new HashMap<String, Object>();
				map.put("cname", u.getCname());
				map.put("username", u.getUsername());
				map.put("dept", EntityUtils.getValue(u, "deptName"));
				ls.add(map);
			}
		} else {
			ls = null;
		}
		return ls;
	}
	
	private IDept getDeptById(String xqtcDeptId) {
		String hql = " from " + Dept.class.getName() + " where ID_=:id";
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("id", xqtcDeptId);
		List<IDept> list = coreHibernateDao.query(hql, map);
		if (list.size() > 0) {
			return list.get(0);
		}
		return null;
	}
}
